package com.watson.onebox.jvm;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import lombok.AllArgsConstructor;
import lombok.Data;
import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.Queue;
import java.util.concurrent.*;

public class GCTest {
    private static Unsafe unsafe;
    static ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("structure-%d").build();
    public static ExecutorService threadPool = new ThreadPoolExecutor(50,
            50,
            60,
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(100),
            threadFactory,
            new ThreadPoolExecutor.DiscardPolicy());

    static {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            unsafe = (Unsafe) field.get(null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static long addressOf(Object o) throws Exception {
        Object[] array = new Object[]{o};
        long baseOffset = unsafe.arrayBaseOffset(Object[].class);
        int addressSize = unsafe.addressSize();
        long objectAddress;
        switch (addressSize) {
            case 4:
                objectAddress = unsafe.getInt(array, baseOffset);
                break;
            case 8:
                objectAddress = unsafe.getLong(array, baseOffset);
                break;
            default:
                throw new Error("unsupported address size: " + addressSize);
        }
        return (objectAddress);
    }

    private static final int _1MB = 1024 * 1024;


    @Data
    @AllArgsConstructor
    static
    class Greeting {
        private String message;
    }

    public static void greeting() {
        Greeting greeting = new Greeting(JmhHello.src);

        Queue<Greeting> objCache = null;
        while (true) {
            if (objCache == null || objCache.size() >= 200000) {
                objCache = new ConcurrentLinkedDeque<>();
                System.out.println("aaaaaa");
            } else {
                objCache.add(greeting);
            }
        }
    }

    static byte[] allocation1 = new byte[2 * _1MB];
    static byte[] allocation2 = new byte[2 * _1MB];
    static byte[] allocation3 = new byte[2 * _1MB];
    static byte[] allocation4 = new byte[4 * _1MB];


    //-XX:+UseG1GC -XX:+PrintGCDetails -Xmx4G  -XX:G1HeapRegionSize=4m

    //-XX:+UseConcMarkSweepGC -Xmx8G -XX:+PrintGCDetails
    //-XX:+PrintGCDetails -Xmx4G


    public static void main(String[] args) throws Exception {
        // 打印对象所在的起始内存地址
//        Thread.sleep(100000);
        while (true) {
            MyThread myThread = new MyThread();
            threadPool.submit(myThread);
        }
//
//        greeting();


    }

}
